home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-02-05 | 9.8 KB | 395 lines | [TEXT/MACA] |
- cat think-c-pap-routines-c.txt
- /* Routines to interface to PAP driver. See MacTutor, Sep '86; also Jan '88.
- This routines are meant to replace the assembly language "glue"
- given in the Sep '86 article. Refer to the article for info on how to
- use these routines.
-
- Sak Wathanasin (sw%kernel.co.uk or ....!mcvax!ukc!kernel!sw)
-
- This file (or a project built from it) can be included in any project
- that wants to talk to the PAP routines, but you must provide two external
- routines, PrintErr and Fatal (they take a Str255 and a short err number).
-
- Synopsis:
-
- typedef struct
- { long systemStuff;
- char statusStr[256];
- } papStatusRec, *papStatusPtr;
-
- pascal short PAPOpen (refNum, printerName, flowQuantum, statusBuf, compState)
- short *refNum;
- char *printerName;
- short flowQuantum;
- papStatusPtr statusBuf;
-
- pascal short PAPRead (refNum, buffer, length, eof, compState);
- short refNum;
- char *buffer;
- short *length;
- short *eol;
- short *compState;
-
- pascal short PAPWrite (refNum, buffer, length, eof, compState)
- short refNum;
- char *buffer;
- short length;
- short eol;
- short *compState;
-
- pascal short PAPClose (refNum);
- short refNum;
-
- typedef struct AddrBlock {
- short aNet;
- Byte aNode;
- Byte aSocket;
- } AddrBlock;
-
- pascal short PAPStatus (printerName, statusBuff, netAddr)
- char *printerName;
- papStatusPtr statusBuff;
- AddrBlock *netAddr;
-
- short PAPLoad ();
- short PAPUnload();
- */
-
- #include "pap.h"
- #define NIL 0L
-
- Handle pap=NIL; /* these static vars don't have to be locked */
- Ptr papPtr; /* points to locked PAP mgr */
- Handle lwNameH; /* handle to locked entity name */
- StringPtr
- lwNameP, /* ptr to same */
- lwTypeP,
- lwZoneP;
-
- #ifdef TEST
- /* test routines divert output to a file, so I can test
- without an LW present */
-
- short psRef=-1;
- struct {
- short *comp,
- len,
- eof;
- Boolean inUse;
- long delay;
- } wInfo= {NIL, 0, 0, FALSE, 0L};
-
- struct {
- short *comp,
- *len,
- *eof;
- char *buff;
- Boolean inUse;
- long delay;
- } rInfo= {NIL, NIL, NIL, NIL, FALSE, 0L};
-
- pascal short PAPOpen (refNum, printerName, flowQuantum, statusBuf, compState)
- short *refNum;
- char *printerName;
- short flowQuantum;
- papStatusPtr statusBuf;
- short *compState;
- {
- # define zeroLoc 10
- static Str255 fName="\pPS Dump 00";
-
- (void)Create(fName, 0, 'PEDT', 'TEXT');
- (void)FSOpen(fName, 0, &psRef);
- if (++fName[zeroLoc] > '9') {
- fName[zeroLoc] = '0';
- fName[zeroLoc-1]++;
- }
-
- *refNum = 0;
- wInfo.comp = compState;
- *compState = 1;
- wInfo.delay = TickCount() + ( Random() % DELAY_FACTOR);
- wInfo.inUse = TRUE;
- return ((short)noErr);
- }
-
-
- pascal short PAPRead (refNum, buffer, length, eof, compState)
- short refNum;
- char *buffer;
- short *length;
- short *eof;
- short *compState;
- {
- long tdelay;
- rInfo.comp = compState;
- *compState = 1;
- rInfo.eof = eof;
- rInfo.len = length;
- rInfo.buff = buffer;
- tdelay = ( Random() % DELAY_FACTOR);
- rInfo.delay = TickCount() + tdelay;
- rInfo.inUse = TRUE;
- return((short)noErr);
- }
-
- pascal short PAPWrite (refNum, buffer, length, eof, compState)
- short refNum;
- char *buffer;
- short length;
- short eof;
- short *compState;
- {
- long psCnt;
- OSErr err=noErr;
- long tdelay;
-
- wInfo.comp = compState;
- *compState = 1;
- wInfo.eof = eof;
- wInfo.len = length;
- tdelay = ( Random() % DELAY_FACTOR);
- wInfo.delay = TickCount() + tdelay;
- if (wInfo.inUse) return (-4101);
- else {
- wInfo.inUse = TRUE;
- psCnt = (long)length;
- err = FSWrite (psRef, &psCnt, buffer);
- return((short)err);
- }
- }
-
- pascal short PAPClose (refNum)
- short refNum;
-
- {
- long psTotal;
-
- wInfo.comp = NIL;
- wInfo.eof = 0;
- wInfo.len = 0;
- wInfo.inUse = FALSE;
- wInfo.delay = 0L;
- rInfo.comp = NIL;
- rInfo.eof = NIL;
- rInfo.len = NIL;
- rInfo.buff = NIL;
- rInfo.inUse = FALSE;
- rInfo.delay = 0L;
- if (psRef >= 0) {
- (void) GetFPos (psRef, &psTotal);
- (void) SetEOF (psRef, psTotal);
- (void)FSClose(psRef);
- (void)FlushVol(nil, 0);
- }
- psRef = -1;
- return(0);
- }
-
- pascal short PAPStatus (printerName, statusBuff, netAddr)
- char *printerName;
- papStatusPtr statusBuff;
- AddrBlock *netAddr;
- {
- static Str255 writing="\p status: writing",
- idle="\p status: idle",
- talking="\p status: talking";
-
- if (wInfo.inUse)
- BlockMove(writing, statusBuff->statusStr, (Size)sizeof(writing));
- else if (rInfo.inUse)
- BlockMove(talking, statusBuff->statusStr, (Size)sizeof(talking));
- else
- BlockMove(idle, statusBuff->statusStr, (Size)sizeof(idle));
- return(0);
- }
-
- extern long randSeed;
- short PAPLoad ()
- {
- static Str255 lw="\pFake LaserWriter",
- lwt="\pLaserWriter",
- lwz="*";
- lwNameP = lw;
- lwTypeP = lwt;
- lwZoneP = lwz;
- GetDateTime(&randSeed);
- return(0);
- }
-
- short PAPUnload()
- {
- return(0);
- }
-
- FakeRead()
- {
- static char rubbish[]="Just some rubbish\n";
-
- if (wInfo.eof) {
- *(rInfo.eof) = 1;
- *(rInfo.len) = 0;
- wInfo.eof = 0;
- }
- else {
- *(rInfo.eof) = 0;
- *(rInfo.len) = sizeof(rubbish)-1;
- BlockMove(rubbish, rInfo.buff, (Size)sizeof(rubbish)-1);
- }
- *(rInfo.comp) = 0;
- rInfo.comp = NIL;
- rInfo.eof = NIL;
- rInfo.len = NIL;
- rInfo.buff = NIL;
- rInfo.inUse = FALSE;
- rInfo.delay = 0L;
- }
-
- FakeWrite()
- {
- *(wInfo.comp) = 0;
- wInfo.comp = NIL;
- wInfo.len = 0;
- wInfo.inUse = FALSE;
- wInfo.delay = 0L;
- }
-
- void TestDelay()
- {
- long myTick;
-
- myTick = TickCount();
- if (rInfo.inUse && myTick > rInfo.delay) FakeRead();
- if (wInfo.inUse && myTick > wInfo.delay) FakeWrite();
- }
-
- #else TEST
- short PAPLoad ()
- { short res;
- OSErr err;
- char NullString='\0';
- Str255 DVolname;
- short DVolRefnum;
- SysEnvRec
- theWorld;
-
- /* we need to find the LaserWriter file on the boot volume
- or 'blessed' folder without making a permanent change
- in the current default volume; under HFS the "poor man's
- search path" is used by default */
-
- (void) SysEnvirons(1, &theWorld);
- (void) GetVol (&DVolname, &DVolRefnum);
- (void) SetVol( &NullString, theWorld.sysVRefNum);
-
- res = OpenResFile ("\pLaserWriter"); /* we should get this name from
- the Chooser (in STR -8192) */
- if ( res < 0 ) {
- /* couldn't find the file */
- Fatal("\pCan't find LaserWriter file", res);
- return (res);
- }
-
- /* Read the PAP code into memory & lock it down */
- if ((pap = GetResource('PDEF', 10)) == NIL || (err = ResError()) ) {
- /* oops! something wrong */
- Fatal("\pCouldn't load PAP resources:", err);
- if (res != -1) /* the file was opened earlier */
- CloseResFile (res);
- return (err);
- };
-
- MoveHHi(pap); /* relocate to top of application heap */
- HLock(pap); /* lock it */
- DetachResource(pap); /* and detach from the file's resource map */
- papPtr = *pap;
- /* save the addr in a global; it's OK to do
- this as we've locked it */
-
- /* Now get the printer entity name from the LaserWriter file */
-
- if ((lwNameH = GetResource('PAPA', -8192)) == NIL || (err = ResError()) ) {
- Fatal("Couldn't get LaserWriter name: ", err);
- return(err);
- }
-
- /* Move to top of heap & lock the name */
- MoveHHi(lwNameH);
- HLock(lwNameH);
- DetachResource(lwNameH);
- lwNameP = (StringPtr)(*lwNameH);
- lwTypeP = lwNameP + (short)lwNameP[0] + 1;
- lwZoneP = lwTypeP + (short)lwTypeP[0] + 1;
-
- /* We're done with the LaserWriter file */
- CloseResFile(res);
- (void) SetVol (&NullString, DVolRefnum);
- return(0);
- }
-
- pascal short PAPOpen ()
- /* no params to stop LSC generating a stack frame */
- {
- asm{
- move.l papPtr, A0
- jmp 0(A0)
- }
- }
-
- pascal short PAPRead ()
- /* no params to stop LSC generating a stack frame */
- {
- asm{
- move.l papPtr, A0
- jmp 4(A0)
- }
- }
-
- pascal short PAPWrite ()
- /* no params to stop LSC generating a stack frame */
- {
- asm{
- move.l papPtr, A0
- jmp 8(A0)
- }
- }
-
- pascal short PAPStatus ()
- /* no params to stop LSC generating a stack frame */
- {
- asm{
- move.l papPtr, A0
- jmp 12(A0)
- }
- }
-
- pascal short PAPClose ()
- /* no params to stop LSC generating a stack frame */
- {
- asm{
- move.l papPtr, A0
- jmp 16(A0)
- }
- }
-
- /* The PAP driver installs several VBL tasks that must be removed
- using the PAP unload call before disposing of the PAP code
- */
- short PAPUnload()
- { short res;
- asm{
- subq.l #2, sp
- move.l papPtr, A0
- jsr 20(A0)
- move.w (sp)+, res /* save the result from the PAP call */
- }
- /* can PAPUnload ever return an error? We assume not... */
-
- HUnlock(lwNameH);
- DisposHandle(lwNameH); /* junk the LW name */
- HUnlock(pap);
- DisposHandle(pap);
- return(res);
- }
- #endif TEST
- command: